package com.authine.cloudpivot.ext.util;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.Assert;
import com.alibaba.cola.exception.BizException;
import com.authine.cloudpivot.common.organization.feign.DepartmentFeignServiceI;
import com.authine.cloudpivot.ext.conf.ApplicationConf;
import com.authine.cloudpivot.ext.domain.vo.MarketGoodsVo;
import com.authine.cloudpivot.ext.domain.vo.OrgVo;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.errorcode.ErrorCodeEnum;
import com.authine.mvp.app.launcher.utils.ModelRuntimeException;
import com.authine.mvp.app.org.dto.domainmodel.DepartmentModel;
import com.authine.mvp.controller.support.LocalDebugAppRouteBean;
import com.authine.mvp.controller.support.LocalDebugHeaderParam;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @program: gm-market
 * @description: 平台工具类
 * @author: wlw
 * @create: 2021-08-11 17:16
 **/
@Slf4j
public class PmUtil {
    private static DepartmentFeignServiceI departmentFeignServiceI = ApplicationContextUtils.getBean(DepartmentFeignServiceI.class);

    private static final Random random = new Random();

    private static final Integer END = 10;

    private static final Integer CAPTCHA_LENGTH = 6;//验证码长度，nextDouble()方法生成的数字精确到小数点后16位，所以验证码长度最大可以到16位。

    private static final String yyyyMMddhhmmss = "yyyy-MM-dd HH:mm:ss";

    private static final String PM_ID = "2c9ac00d78a69a5a0178abeccdb20000";

    private static final OrgVo pmOrg = initOrg();

    private static final String project_url  = initUrl();

    //冀中商城client_id
    private static final String JZ_CLIENT_ID = "KFZEMwpIRg5";


    public static OrgVo getPmOrg(){
        return pmOrg;
    }

    public static String getProjectUrl(){
        return project_url;
    }

    public static Map<String,BigDecimal> calculateSkuPrice(MarketGoodsVo marketGoodsVo){
        log.info("计算价格，商品信息：{}",marketGoodsVo);
        //税后单价
        BigDecimal price = !StringUtils.isEmpty(marketGoodsVo.getAdjust_price())?marketGoodsVo.getAdjust_price():marketGoodsVo.getPrice();
        //供应商id
        String vendorId = marketGoodsVo.getVendor_id().get(0).getId();
        //税率
        BigDecimal taxRate = marketGoodsVo.getTax_rate();
        Assert.isTrue(!StringUtils.isEmpty(price)&&!StringUtils.isEmpty(vendorId)&&!StringUtils.isEmpty(taxRate),"商品价格获取错误");
        Map<String, Object> data = BoServiceUtils.loadByBizObjectId(ApplicationConf.ORGANIZATION, vendorId).getData().getData();
        //运费比例
        BigDecimal freightRatioByOrgId = Optional.ofNullable((BigDecimal)data.get("freight_ratio")).orElse(BigDecimal.ZERO);
        //账期
        BigDecimal statementCycle = Optional.of((new BigDecimal(Optional.ofNullable((String)data.get("statement_cycle")).orElse("0")))).orElse(BigDecimal.ZERO);
        try {
            /**
             * 目前的运算公式为：((0.03 + 供应商运费比例) + (((客户账期/30 向上取整)* 1.5)/100) + 1) * 调整后含税单价(按照调整比例调整后的)
             * 市场展示的售价=市场展示的未税价格*税率
             */
            BigDecimal ceil = BigDecimal.valueOf(Math.ceil(BigDecimalUtils.div(statementCycle,(new BigDecimal(30))).doubleValue()));
            BigDecimal accountPeriodRate = BigDecimalUtils.div(BigDecimalUtils.mul(ceil, BigDecimal.valueOf(1.5)),(BigDecimal.valueOf(100)));
            BigDecimal showPretaxPrice =BigDecimalUtils.mul(price,(BigDecimalUtils.add(BigDecimalUtils.add(ApplicationConf.SHOP_PLATFORM_RATE, freightRatioByOrgId),BigDecimalUtils.add(BigDecimal.ONE,accountPeriodRate)))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal showPrice = BigDecimalUtils.round(BigDecimalUtils.mul(showPretaxPrice, BigDecimal.ONE.add(taxRate)), 2);
            HashMap<String, BigDecimal> map = Maps.newHashMap();
            map.put("showPretaxPrice",showPretaxPrice);
            map.put("showPrice",showPrice);
            return map;
        } catch (Exception e) {
            log.error("计算商品未税单价异常",e);
            throw new BizException("商品价格获取错误");
        }
    }

    /**
     * 初始化平台信息
     * @return
     */
    private static OrgVo initOrg(){
        SingleResponse<BO> singleResponse = BoServiceUtils.loadByBizObjectId(ApplicationConf.ORGANIZATION, PM_ID);
        return BoUtils.Map2Bo(singleResponse.getData().getData(), OrgVo.class);
    }

    /**
     * 项目工程url,nginx暴露ip
     * @return
     */
    private static String initUrl(){
        String url = PmUtil.getUrl("app-lifecycle");
        String api = "/cloudpivot/deployment/info";
        Map data = RestTemplateUtil.rest(url.concat(api), null, HttpMethod.GET);
        return (String)((Map)data.get("data")).get("url");
    }


    /**
     * 当前用户是否是平台
     */
    public static boolean isPm() {
        return Objects.equals(getOrgOrganization("").getId(), PM_ID);
    }


    /**
     * 小数点后面不需要的0
     */
    public static BigDecimal numberFormat(BigDecimal bigDecimal) {
        // 平台id为1
        if (Objects.isNull(bigDecimal)){
            return BigDecimal.ZERO;
        }
        if (bigDecimal.scale() >= 0) {
            return bigDecimal.stripTrailingZeros();
        }
        return bigDecimal;
    }

    /**
     * 查询当前用户根组织
     * @return
     */
/*    public static DepartmentModel getOrgRootOrganization(@Nullable String id){
        if(StringUtils.isEmpty(id)){
            id = RequestContext.getCorpLoginId();
        }
        List list = departmentFeignServiceI.getUserParentDepartments(id).getData();
        if(!CollectionUtils.isEmpty(list)){
            try {
                Map o = (Map)list.stream().filter(v ->  StringUtils.isEmpty(((Map) v).get("parentId"))).findAny().orElseThrow(() -> new BizException("未查询到当前根组织"));
                return BoUtils.Map2Bo(o, DepartmentModel.class);
            } catch (Throwable throwable) {
                log.error("[PmUtil] find orgRoot exception",throwable);
            }
        }
        return null;
    }*/

    /**
     * 查询当前用户组织信息
     * @return
     */
    public static OrgVo getOrgOrganization(@Nullable String id){
        if(StringUtils.isEmpty(id)){
            id = RequestContext.getCorpLoginId();
        }
            try {
                log.info("id ======》{}",id);
                BO data = BoServiceUtils.loadByBizObjectId(ApplicationConf.USER, id).getData();
                log.info("用户信息===========》{}",data);
                if(Objects.nonNull(data.getData())){
                    SelectorFormat organizationId = (SelectorFormat) CollectionUtils.firstElement((List)(data.getData().get("organization_id")));
                    BO organization = BoServiceUtils.loadByBizObjectId(ApplicationConf.ORGANIZATION, organizationId.getId()).getData();
                    log.info("机构信息==========》{}",organization);
                    return Optional.ofNullable(organization).map(v->BoUtils.Map2Bo(v.getData(),OrgVo.class)).orElseThrow(()-> new BizException("未查询到当前用户组织信息"));
                }
            } catch (Throwable throwable) {
                log.error("[PmUtil] find orgRoot exception",throwable);
                throw new BizException("查询用户组织信息错误");
            }
        return null;
    }


    //创建随机6位数字验证码
    public static String createCode() {
        Double pross = random.nextDouble() * Math.pow(END, CAPTCHA_LENGTH);
        return String.format("%06.0f", pross);
    }

    /**
     * 获取当前用户信息
     * @return
     */
    public static String getCurrentUserId(){
        String loginId = RequestContext.getCorpLoginId();//297e657673ffad1d0174001bf88e0012
        if(StringUtils.isEmpty(loginId)){
            throw new ModelRuntimeException(ErrorCodeEnum.BIZ_PARAMS_ERR,"当前登录用户cropLoginId为空，请先登录;\n");
        }
        return loginId;
    }

    /**
     * 格式化起始时间
     * @param type
     * @param count
     * @return
     */
    public static String getStartDateStr(int type,int count){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.add(type,count);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 格式化结束时间
     * @param type
     * @param count
     * @return
     */
    public static String getEndDateStr(int type,int count){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        calendar.add(type,count);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 获取指定应用内网ip
     * @param appCode
     * @return
     */
    public static String getUrl(String appCode) {
        Environment environment = ApplicationContextUtils.getBean(Environment.class);
        String property = environment.getProperty("debugApplicationService");
        log.info("[debugApplicationService] ：{}",property);
        if ("false".equals(property)||(StringUtils.isEmpty(property)&&!appCode.contains("app"))) {
            LocalDebugAppRouteBean localDebugAppRouteBean = ApplicationContextUtils.getBean(LocalDebugAppRouteBean.class);
            return localDebugAppRouteBean.getBaseUrl(appCode, LocalDebugHeaderParam.builder()
                    .requestId(RequestContext.getRequestId()).loginName(RequestContext.getLoginName())
                    .requestId(RequestContext.getRequestId()).build());
        }
        DiscoveryClient discoveryClient = ApplicationContextUtils.getBean(DiscoveryClient.class);
        String serviceId = appCode.contains("app")?appCode:"app-launcher-" + appCode;
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
        if (CollectionUtils.isEmpty(instances)) {
            return null;
        }
        for (ServiceInstance instance : instances) {
            Map<String, String> metadata = instance.getMetadata();
            String nodeIp = metadata.get("nodeIp");
            String nodePortStr = metadata.get("nodePort");
            return new DefaultServiceInstance(instance.getInstanceId(), instance.getServiceId(), nodeIp, Integer.parseInt(nodePortStr), false).getUri().toString();
        }
        return null;
    }

    /**
     * 格式化部门
     * @param id
     * @return
     */
    public static SelectorFormat orgFormat(String id){
        BO organization = BoServiceUtils.loadByBizObjectId(ApplicationConf.ORGANIZATION, id).getData();
        SelectorFormat selectorFormat = new SelectorFormat();
        selectorFormat.setId(id);
        selectorFormat.setType(1);
        selectorFormat.setName((String)(organization.getData().get("name")));
        return selectorFormat;
    }

    /**
     * 格式化时间
     */
    public static String dateFormatStr(Date date){
        SimpleDateFormat dateFormat = new SimpleDateFormat(yyyyMMddhhmmss);
        return dateFormat.format(date);
    }

    /**
     * 格式化用户
     * @return
     */
    public static SelectorFormat userFormat(){
        SelectorFormat selectorFormat = new SelectorFormat();
        selectorFormat.setId(RequestContext.getCorpLoginId());
        selectorFormat.setType(3);
        selectorFormat.setName(RequestContext.getLoginName());
        return selectorFormat;
    }

    /**
     * 数组条件查询处理
     * @param c
     * @return
     */
    public static List<String>  listFormatSqlString(List<String> c){
        if(!CollectionUtils.isEmpty(c)){
            return c.stream().map(t->"'".concat(t).concat("'")).collect(Collectors.toList());
        }
        return Lists.newArrayList();
    }

    public static void main(String[] args) {
    }

}
